package org.piax.rospubsub;

import java.io.IOException;
import java.net.InetSocketAddress;

/**
 * ROS の世界と DTN の世界を仲立ちするFacadeクラス
 */
public class ROSDTNProxy {
    private InetSocketAddress rosMaster = null;     // subscribe時の通知先 ROS master
    private int publishCtrlPort = -1;               // publish 要求受け付けポート番号
    private InetSocketAddress adbForward = null;    // ADB forward のPC側接続先

    private ADBBridge adbBridge = null;             // ADB 経由の通信路
    private PublishRequestListener publishListeer = null;  // ROS -> DTN publish要求受け付けクラス
    private SubscribeProxy subscribeProxy = null;   // DTN -> ROS (subscribe)  用 proxy

    private boolean running = false;                // 動作中フラグ. true で動作中

    /**
     * コンストラクタ
     * @param ros_master ROSマスター接続先
     * @param publish_ctrl_port publish 要求受け付けポート番号
     * @param adb_fwd ADB forward PC側接続先
     */
    public ROSDTNProxy(InetSocketAddress ros_master, int publish_ctrl_port, InetSocketAddress adb_fwd) {
        if (ros_master == null)
            throw new IllegalArgumentException("ros_master should not be null");
        if (ros_master.isUnresolved())
            throw new IllegalArgumentException("ros_master should be resolved");
        if (publish_ctrl_port < 0 || 65535 < publish_ctrl_port)
            throw new IllegalArgumentException("publish_ctrl_port should be in 16bit num");
        if (adb_fwd == null)
            throw new IllegalArgumentException("adb_fwd should not be null");
        if (adb_fwd.isUnresolved())
            throw new IllegalArgumentException("adb_fwd should be resolved");

        rosMaster = ros_master;
        publishCtrlPort = publish_ctrl_port;
        adbForward = adb_fwd;
    }

    /**
     * ROS <-> DTN proxy を開始する。
     * @throws IOException
     */
    public synchronized void start() throws IOException {
        if (running)
            throw new IllegalStateException("ROS-DTN proxy is already started.");

        adbBridge = new ADBBridge();
        publishListeer = new PublishRequestListener(adbBridge, publishCtrlPort, 8*1024);
        subscribeProxy = new SubscribeProxy(adbBridge, rosMaster);
        adbBridge.open(adbForward, subscribeProxy);

        publishListeer.start();
        subscribeProxy.start();
        running = true;
    }

    /**
     * ROS <-> DTN proxy を停止する。
     * @throws IOException
     * @throws InterruptedException 
     */
    public void stop() throws IOException, InterruptedException {
        if (!running)
            return;

        adbBridge.close();
        publishListeer.stop();
        subscribeProxy.stop();
        running = false;
    }
}
